#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <lm.h>
#include <stdio.h>
#include <stdlib.h>

/*
 * Code from ca/pginst.ca
 *
 * Attempts to load external DLLs to see if they are present. This program
 * attempts to load them one by one to detect where a crash or hang 
 * happens.
 */


static void CheckDC(void)
{
	OSVERSIONINFOEX verinfo;

	ZeroMemory(&verinfo,sizeof(verinfo));
	verinfo.dwOSVersionInfoSize = sizeof(verinfo);
	
	if (!GetVersionEx((OSVERSIONINFO*)&verinfo))
	{
		printf("Failed to retreive OS version!\n");fflush(stdout);
		return;
	}
	if (verinfo.wProductType == VER_NT_DOMAIN_CONTROLLER)
	{
		/* Machine is a domain controller. So get the domain and set as dflt */
		WKSTA_INFO_100 *wkinfo = NULL;
		NET_API_STATUS status;

		printf("Detected domain controller!\n");fflush(stdout);
		status = NetWkstaGetInfo(NULL, 100, (LPBYTE*)&wkinfo);
		if (status != NERR_Success)
		{
			printf("Faield to retreive workstation information!");fflush(stdout);
			return;
		}

		printf("Setting local domain to %S\n",wkinfo->wki100_langroup);

		if (wkinfo != NULL)
			NetApiBufferFree(wkinfo);
	}
	else
	{
		/* Not a domain controller - default to computer name */
		char tmpname[256];
		DWORD sz = sizeof(tmpname)-1;
		printf("Detected non-domaincontroller\n");fflush(stdout);

		ZeroMemory(tmpname,sizeof(tmpname));
		if (!GetComputerName(tmpname, &sz))
		{
			printf("Failed to get local computer name!\n");fflush(stdout);
			return;
		}
		printf("Setting local domain to %s\n",tmpname);fflush(stdout);
	}
}

static void CheckOneDll(char *dllname, char *propertyname)
{
	HANDLE hLib;

	SetLastError(0);
	printf("About to load '%s'\n",dllname);fflush(stdout);
	hLib = LoadLibraryEx(dllname, NULL, 0);
	printf("LoadLibraryEx() is back with %08x: %i\n", hLib, GetLastError());fflush(stdout);
	if (hLib == NULL)
	{
		printf("Library '%s' not found, setting '%s' to 0\n",dllname,propertyname);fflush(stdout);
	}
	else
	{
		printf("Library '%s' found and loaded, setting '%s' to 1\n",dllname,propertyname);fflush(stdout);
		FreeLibrary(hLib);
		printf("Library unloaded.\n");fflush(stdout);
	}
}

/*
 * Check if required DLLs are loadable
 */
void CheckAvailableDLLs(void)
{
#define ONEDLL(dll,prop) {CheckOneDll(dll,prop);}

	ONEDLL("perl58.dll","HAS_PERL");
	ONEDLL("tcl84.dll","HAS_TCL");
	ONEDLL("python23.dll","HAS_PYTHON");

	printf("About to check DC!\n");fflush(stdout);
	CheckDC();
	printf("All checks done!\n");fflush(stdout);
}


int main(int argc, char *argv[])
{
	CheckAvailableDLLs();
}
